﻿#include "stdio.h"
#include "conio.h"
#include "string.h"

char prog[80], token[8];
int syn, p, m, n, sum = 0;
char ch;
char r0[] = "begin";
char r1[] = "if";
char r2[] = "then";
char r3[] = "while";
char r4[] = "do";
char r5[] = "endl";
char* rwtab[6] = { r0,r1,r2,r3,r4,r5 };

void lrparser();
void yucu();
void statement();
void expression();
void term();
void factor();
int kk = 0;

void scaner() {
	m = 0;
	for (n = 0; n < 8; n++) token[n] = NULL;
	ch = prog[p++];
	while (ch == ' ') ch = prog[p++];
	if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {
		while ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9')) {
			token[m++] = ch;
			ch = prog[p++];
		}
		token[m++] = '\0';
		syn = 10;
		p = p - 1;      //回退一个字符
		for (n = 0; n < 6; n++) {
			if (strcmp(token, rwtab[n]) == 0) {
				syn = n + 1;
				break;
			}
		}
	}
	else if (ch >= '0' && ch <= '9') {
		sum = 0;
		while (ch >= '0' && ch <= '9') {
			sum = sum * 10 + ch - '0';
			ch = prog[p++];
		}
		p = p - 1;
		syn = 11;
	}
	else {
		switch (ch) {
		case '<':
			m = 0;
			token[m++] = ch;
			ch = prog[p];
			if (ch == '>') {
				syn = 21;
				token[m++] = ch;
			}
			else if (ch == '=') {
				syn = 22;
				token[m++] = ch;
			}
			else {
				syn = 20;
				p = p - 1;
			}
			p = p + 1;
			token[m] = '\0';
			break;
		case '>':
			m = 0;
			token[m++] = ch;
			ch = prog[p++];
			if (ch == '=') {
				syn = 24;
				token[m++] = ch;
			}
			else {
				syn = 23;
				p = p - 1;
			}
			break;
		case ':':
			m = 0;
			token[m++] = ch;
			ch = prog[p++];
			if (ch == '=') {
				syn = 18;
				token[m++] = ch;
			}
			else {
				syn = 17;
				p = p - 1;
			}
			break;
		case '+':
			syn = 13;
			token[0] = ch;
			break;
		case '-':
			syn = 14;
			token[0] = ch;
			break;
		case '*':
			syn = 15;
			token[0] = ch;
			break;
		case '/':
			syn = 16;
			token[0] = ch;
			break;
		case ';':
			syn = 26;
			token[0] = ch;
			break;
		case '(':
			syn = 27;
			token[0] = ch;
			break;
		case ')':
			syn = 28;
			token[0] = ch;
			break;
		case '=':
			syn = 25;
			token[0] = ch;
			break;
		case '#':
			syn = 0;
			token[0] = ch;
			break;
		default:
			syn = -1;
		}
	}
}
void lrparser() {
	if (syn == 1) { //begin
		scaner();
		yucu();
		if (syn == 6) { //end
			scaner();
			if (syn == 0 && kk == 0) printf("success \n");
		}
		else {
			if (kk != 1) printf("error,lose 'endl' ! \n");
			kk = 1;
		}
	}
	else {
		printf("error,lose 'begin' ! \n");
		kk = 1;
	}
	return;
}

void yucu() {
	statement();
	while (syn == 26) {
		scaner();
		statement();
	}
	return;
}

void statement() {
	if (syn == 10) { //为标识符
		scaner();
		if (syn == 18) { //为 :=
			scaner();
			expression();
		}
		else {
			printf("error!");
			kk = 1;
		}
	}
	else {
		printf("error!");
		kk = 1;
	}
	return;
}


void expression() {
	term();
	while (syn == 13 || syn == 14) {
		scaner();
		term();
	}
	return;
}


void term() {
	factor();
	while (syn == 15 || syn == 16) {
		scaner();
		factor();
	}
	return;
}


void factor() {
	if (syn == 10 || syn == 11)scaner(); //为标识符或整常数时，读下一个单词符号
	else if (syn == 27) {
		scaner();
		expression();
		if (syn == 28)scaner();
		else {
			printf(" ')' 错误\n");
			kk = 1;
		}
	}
	else {
		printf("表达式错误\n");
		kk = 1;
	}
	return;
}


int main() {
	p = 0;   //int i;
	printf("********************语法分析程序***************\n");
	printf("请输入单词串:\n");
	do {
		scanf_s("%c", &ch);
		prog[p++] = ch;
	} while (ch != '#');
	p = 0;
	scaner();
	lrparser();
	printf("语法分析结束！\n");
	//getch();
	return 0;
}
